<?php
require_once('pworks/mvc/IConfigHelper.iface.php');
require_once('pworks/util/ClassLoader.class.php');
require_once('pworks/common/exception/SystemException.class.php');
require_once('pworks/util/DebugUtil.class.php');

class ConfChecker{
    public static function check(IConfigHelper $helper){

//DebugUtil::dump($helper->getApp()->actions, __FILE__, __LINE__);
        foreach($helper->getApp()->actions as $actionConf){
            if(!self::checkAction($actionConf->id, $helper)){
                return false;
            }
        }
//echo DebugUtil::GRADE_END;
        if($helper->getActionConfig($helper->getDefaultAction()) == null){
            throw new SystemException(SystemException::FRAMEWORK_ERROR, "Default Action is not valid!");
            return false;
        }
        return true;
    }

    private static function checkAction($actionId, IConfigHelper $helper){
        $actionConf = $helper->getActionConfig($actionId);
//echo "<hr>";        
//DebugUtil::dump($actionConf, __FILE__, __LINE__);
        if($actionConf ==  null){
            throw new SystemException(SystemException::FRAMEWORK_ERROR, "Action '$actionId' has not been defined yet!");
            return false;
        }
//DebugUtil::point(__FILE__, __LINE__);
        try{
            ClassLoader::isClassExist($actionConf->clzName);
        }catch(SystemException $e){
            throw new SystemException(SystemException::FRAMEWORK_ERROR, "Invalid class of action '$actionId':{$e->message}");
            return false;
        }
//DebugUtil::point(__FILE__, __LINE__);
        if(is_array($actionConf->filters)){
            foreach($actionConf->filters as $filterRefId){
                if(!self::checkFilter($actionId, $filterRefId, $helper)){
                    return false;
                }
            }
        }

//DebugUtil::dump($actionConf->results, __FILE__, __LINE__);
        if(is_array($actionConf->results)){
            foreach($actionConf->results as $rsConf){
                if(!self::checkResult($actionId, 'action', $rsConf, $helper)){
                    return false;
                }
            }
        }
  
        return true;
    }

    private static function checkFilter($actionId, $filterRefId, IConfigHelper $helper){
        $filterConf = $helper->getFilterConfig($filterRefId);

//DebugUtil::dump($filterConf, __FILE__, __LINE__); 
        if($filterConf == null){
            throw new SystemException(SystemException::FRAMEWORK_ERROR, "Filter '$filterRefId' of Action '$actionId' has not been defined yet!");
            return false;
        }

        try{
            ClassLoader::isClassExist($filterConf->clzName);
        }catch(SystemException $e){
            throw new SystemException(SystemException::FRAMEWORK_ERROR, "Invalid class of filter '$filterRefId':{$e->message}");
            return false;
        }
        

        if(is_array($filterConf->results)){
            foreach($filterConf->results as $rsConf){
                if(!self::checkResult($filterRefId, 'filter', $rsConf, $helper)){
                    return false;
                }
            }
        }
        return true;
    }

    private static function checkResult($ownerId, $ownerType,ResultConfig $rsConf, IConfigHelper $helper){
        //check Result Type
        $rsTypeConf = $helper->getResultType($rsConf->type);
//DebugUtil::dump($rsTypeConf, __FILE__, __LINE__);

//DebugUtil::dump($rsConf, __FILE__, __LINE__);
        if($rsTypeConf == null){
            throw new SystemException(SystemException::FRAMEWORK_ERROR, "Result type of result '{$rsConf->id}' of $ownerType '$ownerId' has not been defined yet!");
            return false;
        }

        try{
            ClassLoader::isClassExist($rsTypeConf->clzName);
        }catch(SystemException $e){
            throw new SystemException(SystemException::FRAMEWORK_ERROR, "Invalid class of result type '{$rsConf->type}':{$e->message}");
            return false;
        }

        //check src file
        $src = $rsConf->src;
        $tmpRoot = $helper->getGlobal('template_root_path');
        if($tmpRoot !=null && strlen(trim($tmpRoot))>0){
            $src =  trim($tmpRoot) . '/' . $src;
        }
        if(!file_exists($src)){
            throw new SystemException(SystemException::FRAMEWORK_ERROR, "The tmplate source '$src' that be used by the result '{$rsConf->id}' of $ownerType '$ownerId' could not be found!");
            return false;
        }
        
        return true;
    }

    //TODO not completed yet!
    public static function checkUnused(IConfigHelper $helper){
        $unusedList = array();

        //check unused filters
        $unusedFilters = array();
        //TODO

        //check unused result type
        $unusedRsType = array();
        //TODO

        $unusedList['filter'] = $unusedFilters;
        $unusedList['rstype'] = $unusedRsType;
        return $unusedList;
    }
}
